/*
 * Sonatype Nexus (TM) Open Source Version
 * Copyright (c) 2008-present Sonatype, Inc.
 * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
 *
 * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
 * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
 *
 * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
 * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
 * Eclipse Foundation. All other trademarks are the property of their respective owners.
 */
package org.sonatype.nexus.repository.vulnerability;

import java.util.Arrays;

import org.apache.commons.lang3.Range;

/**
 * Mapping between IQ and NPM
 *
 * @since 3.next
 */
public enum SeverityLevel
{
  CRITICAL("critical", "critical", Range.between(8, 10)),
  HIGH("high", "severe", Range.between(4, 7)),
  MODERATE("moderate", "moderate", Range.between(2, 3)),
  LOW("low", null, Range.between(0, 1));

  private final String npmLevel;

  private final String iqLevel;

  private final Range<Integer> severityRange;

  SeverityLevel(final String npmLevel, final String iqLevel, final Range<Integer> severityRange) {
    this.npmLevel = npmLevel;
    this.iqLevel = iqLevel;
    this.severityRange = severityRange;
  }

  public static SeverityLevel calculateThreatCategory(final int threatLevel) {
    return Arrays.stream(SeverityLevel.values())
        .filter(level -> level.severityRange.contains(threatLevel))
        .findFirst()
        .orElseThrow(IllegalArgumentException::new);
  }

  public String getIqLevel() {
    return iqLevel;
  }

  public String getNpmLevel() {
    return npmLevel;
  }

  public Range<Integer> getSeverityRange() {
    return severityRange;
  }

  @Override
  public String toString() {
    return String.format("npm lvl [%s] iq lvl [%s] severity range %s", npmLevel, iqLevel, severityRange);
  }

  public static SeverityLevel getSeverityLevelByIq(String iqLevel) {
    return Arrays.stream(SeverityLevel.values())
        .filter(a -> iqLevel.equalsIgnoreCase(a.getIqLevel()))
        .findFirst().orElseThrow(() -> new IllegalArgumentException(iqLevel));
  }
}
